package windowUnits;

import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.util.Enumeration;

import javax.swing.JComponent;
import javax.swing.JOptionPane;
import javax.swing.JTree;
import javax.swing.SwingUtilities;
import javax.swing.TransferHandler;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreePath;

import sqlServer.BaseDataObject;
import sqlServer.Menus;

public class TreeTransferHandler extends TransferHandler {
	/**
	 * 
	 */
	private static final long serialVersionUID = 2835835852210029872L;
	
	final public static DataFlavor DEFAULT_MUTABLE_TREENODE_FLAVOR = new DataFlavor(
			DefaultMutableTreeNode.class, "Default Mutable Tree Node");
	public boolean canImport(TransferHandler.TransferSupport info) {
		// we only import Strings
		if (!info.isDataFlavorSupported(DEFAULT_MUTABLE_TREENODE_FLAVOR)) { 
			return false; 
			}
		/*
		 * if (!info.isDataFlavorSupported(DataFlavor.stringFlavor)) { return
		 * false; }
		 * 
		 * JList.DropLocation dl = (JList.DropLocation)info.getDropLocation();
		 * if (dl.getIndex() == -1) { return false; }
		 */
		return true;
	}

	public boolean importData(TransferHandler.TransferSupport
	info) {
	              if (!info.isDrop()) {
	                  return false;
	              }
	              
	              // Check for String flavor
	              if (!info.isDataFlavorSupported(DEFAULT_MUTABLE_TREENODE_FLAVOR))
	              {
	                  displayDropLocation("List doesn't accept a drop of this type.");
	                  return false;
	              }
	              
	              JTree.DropLocation dl =
	            	  (JTree.DropLocation)info.getDropLocation();
	              // DefaultListModel listModel =(DefaultListModel)list.getModel();
	              // int index = dl.getIndex();
	              TreePath insert = dl.getPath();
	              
	              // Get the current string under the drop.
	              // String value = (String)listModel.getElementAt(index);
	              // displayDropLocation("path "+insert.toString());
	              // Get the string that is being dropped.
	              Transferable t = info.getTransferable();
	              
	              Menus data;
	              try {
	                  data = (Menus)t.getTransferData(DEFAULT_MUTABLE_TREENODE_FLAVOR);
	              } 
	              catch (Exception e) { return false; }
	              
	              DefaultMutableTreeNode node =	(DefaultMutableTreeNode)insert.getLastPathComponent();
	              
	              //displayDropLocation( data+ " /path "+dl.getChildIndex()+"	/ "+node);
	              // Display a dialog with the drop information.
	              //String dropValue = "\"" + data + "\" dropped ";
	              DefaultTreeModel model = (DefaultTreeModel)((JTree)info.getComponent()).getModel();
				  
				  DefaultMutableTreeNode transferedNode = (DefaultMutableTreeNode)((JTree)info.getComponent()).getSelectionPath().getLastPathComponent();
				  
				  DefaultMutableTreeNode insNode = new DefaultMutableTreeNode();
				  insNode = getNodeToCopy(transferedNode);
				  
				  if(node.getUserObject().equals(transferedNode.getUserObject())){
					  return false;
				  }
				  
				  if(dl.getChildIndex() != -1)
					model.insertNodeInto(insNode, node, dl.getChildIndex());
				  else
					model.insertNodeInto(insNode, node, node.getChildCount());
				  
				  DefaultMutableTreeNode parantNodeTransferedFrom = (DefaultMutableTreeNode)transferedNode.getParent();
				  if(parantNodeTransferedFrom.equals(node)){
					  System.out.println("same node");
					  ((BaseDataObject)node.getUserObject()).setChanged(true);
					  ((BaseDataObject)node.getUserObject()).setOrderChanged(true);
					  
				  }else{
					  System.out.println("diferent Node: "+node);
					  
					  ((BaseDataObject)node.getUserObject()).setChanged(true);
					  ((BaseDataObject)node.getUserObject()).setOrderChanged(true);
					  ((BaseDataObject)node.getUserObject()).addObjectOnSave((BaseDataObject)transferedNode.getUserObject());
				  
					  ((BaseDataObject)parantNodeTransferedFrom.getUserObject()).setChanged(true);
					  ((BaseDataObject)parantNodeTransferedFrom.getUserObject()).setOrderChanged(true);
					  ((BaseDataObject)parantNodeTransferedFrom.getUserObject()).removeObjectOnSave((BaseDataObject)transferedNode.getUserObject());
				  }
				  
				  model.removeNodeFromParent(transferedNode);
				  
				  
				  
				  /*
					 * if (dl.isInsert()) { if (dl.getIndex() == 0) {
					 * displayDropLocation(dropValue + "at beginning of list"); }
					 * else if (dl.getIndex() >= list.getModel().getSize()) {
					 * displayDropLocation(dropValue + "at end of list"); } else {
					 * String value1 =
					 * (String)list.getModel().getElementAt(dl.getIndex() - 1);
					 * String value2 =
					 * (String)list.getModel().getElementAt(dl.getIndex());
					 * displayDropLocation(dropValue + "between \"" + value1 +
					 * "\" and \"" + value2 + "\""); } } else {
					 * displayDropLocation(dropValue + "on top of " + "\"" +
					 * value + "\""); }
					 */
			/**
			 * This is commented out for the basicdemo.html tutorial page. * If
			 * you add this code snippet back and delete the * "return false;"
			 * line, the list will accept drops * of type string. // Perform the
			 * actual import. if (insert) { listModel.add(index, data); } else {
			 * listModel.set(index, data); } return true;
			 */
			return false;
	          }

	public int getSourceActions(JComponent c) {
		return COPY;
	}
	
	private DefaultMutableTreeNode getNodeToCopy(DefaultMutableTreeNode node){
		DefaultMutableTreeNode insNode = new DefaultMutableTreeNode(); 
		insNode.setUserObject(node.getUserObject());
		
		Enumeration nodesToUpdate = node.children();
		while(nodesToUpdate.hasMoreElements()){
			DefaultMutableTreeNode child = (DefaultMutableTreeNode)nodesToUpdate.nextElement();
			insNode.add(getNodeToCopy(child));
		}
		
		return insNode;
	}
	
	protected Transferable createTransferable(JComponent c) {
		JTree list = (JTree) c;
		// Object values = list.getLastSelectedPathComponent();

		Transferable tr = new TransferableTreeNode((DefaultMutableTreeNode)list.getLastSelectedPathComponent());
		return tr;
	}

	private void displayDropLocation(final String string) {
		SwingUtilities.invokeLater(new Runnable() {
			public void run() {
				JOptionPane.showMessageDialog(null, string);
			}
		});
	}
}
